package com.qiangqiang.task.server.service;

import com.qiangqiang.task.server.consts.TimeConst;
import com.qiangqiang.task.server.dto.TaskDTO;
import com.qiangqiang.task.server.dto.TaskMessageDTO;
import com.qiangqiang.task.server.entity.Commission;
import com.qiangqiang.task.server.entity.Message;
import com.qiangqiang.task.server.entity.Task;
import com.qiangqiang.task.server.enums.TaskEnum;
import com.qiangqiang.task.server.exception.TaskException;
import com.qiangqiang.task.server.mapper.*;
import com.qiangqiang.task.server.redis.LockPrefix;
import com.qiangqiang.task.server.redis.RedisService;
import com.qiangqiang.task.server.redis.TaskPrefix;
import com.qiangqiang.task.server.util.SnowflakeIdWorker;
import lombok.Data;
import org.apache.ibatis.annotations.Param;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import java.util.List;
import java.util.stream.Collectors;

@Service
public class TaskService extends BaseService {

    @Autowired
    private RedisService redisService;

    @Autowired
    private TaskMapper taskMapper;

    @Autowired
    private ReceviedTaskMapper receviedTaskMapper;

    @Autowired
    private NotificationService notificationService;

    @Autowired
    private MessageMapper messageMapper;

    @Autowired
    private UserMapper userMapper;

    @Autowired
    private CommissionMapper commissionMapper;

    SnowflakeIdWorker userIdWorker = new SnowflakeIdWorker(0, 2);

    SnowflakeIdWorker messageWorker = new SnowflakeIdWorker(0, 8);

    SnowflakeIdWorker commissionWorker = new SnowflakeIdWorker(0, 9);


    /**
     * @param [userId, taskId]
     *                 userId:抢单者id
     *                 taskId:任务id
     * @return void
     * @author sky
     * @date 2018/7/12
     * @describe: 领取任务接口
     */
    public void receiveTask(long receiverId, long taskId) {

        //redis 缓存 是否已经被抢了
        if (!redisService.isReceived(taskId)) {
            throw new TaskException(TaskEnum.TASK_IS_RECEIVED);
        }
        //分布式锁,轮询时间设为 20 ms，其实不应该是轮询锁的
        String identifier = redisService.tryLock(LockPrefix.lockPrefix, taskId, 20);
        if (StringUtils.isEmpty(identifier)) {
            //获取分布式锁失败
            throw new TaskException(TaskEnum.TASK_IS_RECEIVED);
        }
        //获取订单状态
        Task task = taskMapper.findByTaskId(taskId);
        if (task.getStatus() != 0) {
            throw new TaskException(TaskEnum.TASK_STATUS_ERROR);
        }
        //更改状态
        taskMapper.updateTaskByReceiverId(receiverId, taskId);
//        long publisherId = taskMapper.findUserIdByTaskId(taskId);
//        //更新到被抢的表中
//        ReceviedTask receviedTask = new ReceviedTask();
//        receviedTask.setTaskId(taskId);
//        receviedTask.setReceviedTaskId(147);
//        receviedTask.setReceiverId(receiverId);
//        receviedTask.setUserId(publisherId);
//        //消息队列实现异步
//        amqpTemplate.convertAndSend("task",JsonUtil.beanToString(receviedTask));
        //标志 委托已被抢
        redisService.set(TaskPrefix.taskIdPrefix, taskId, identifier);
        // 释放锁
        redisService.releaseLock(LockPrefix.lockPrefix, taskId, identifier);

        // 发送消息
        TaskMessageDTO taskMessageDTO = new TaskMessageDTO();
        taskMessageDTO.setAchievement(userMapper.queryUserById(receiverId).getAchievement());
        notificationService.notifyUser(receiverId, task.getUserId(), 2, taskMessageDTO);

        // 持久化消息
        Message message = new Message();
        message.setMessageId(messageWorker.nextId());
        message.setFromId(receiverId);
        message.setToId(task.getUserId());
        message.setCommonId(taskId);
        message.setType(2);
        message.setCreateTime(TimeConst.nowTimeMilli);
        message.setUpdateTime(TimeConst.nowTimeMilli);
        messageMapper.insertMessage(message);
    }

    /**
     * @param [page, pageSize]
     * @return java.util.List<com.qiangqiang.task.server.entity.Task>
     * @author sky
     * @date 2018/7/12
     * @describe: 分页查询所有未领取的 任务
     */
    public List<TaskDTO> findAllByStatus(int page, int pageSize) {
        return taskMapper.findAllByStatus(page, pageSize).stream().
                map(this::beanToDTO).collect(Collectors.toList());
    }

    /**
     * @Description: 根据userId查找领取/被领取的任务
     * @Param:
     * @return:
     * @Author: sky.lin
     * @Date: 2018/12/17
     */
    public List<TaskDTO> findAllByUserId(int page, int pageSize, long userId, boolean isReceviedId) {
        return taskMapper.findAllByUserId(page, pageSize, userId, isReceviedId).stream().
                map(this::beanToDTO).collect(Collectors.toList());
    }

    public Integer findStatusByTaskId(long taskId) {
        return taskMapper.findStatusByTaskId(taskId);
    }

    /**
     * @Description: 新增委托
     * @Param:
     * @return:
     * @Author: sky.lin
     * @Date: 2018/12/18
     */
    public boolean addTask(Task task) {
        task.setTaskId(userIdWorker.nextId());
        task.setCreateTime(TimeConst.nowTimeMilli);
        task.setUpdateTime(TimeConst.nowTimeMilli);
        task.setEndTime(TimeConst.nowTimeMilli + TimeConst.dayMilli);
        task.setStatus(0);
        return taskMapper.insertTask(task) > 0;
    }

    public boolean finishTask(long taskId) {
        taskMapper.updateStatusByTaskId(taskId, 2);

        Task task = taskMapper.findByTaskId(taskId);

        // 发送消息
        TaskMessageDTO taskMessageDTO = new TaskMessageDTO();
        taskMessageDTO.setAchievement(userMapper.queryUserById(task.getUserId()).getAchievement());
        notificationService.notifyUser(task.getUserId(), task.getReceiverId(), 3, taskMessageDTO);

        // 持久化消息
        Message message = new Message();
        message.setMessageId(messageWorker.nextId());
        message.setFromId(task.getUserId());
        message.setToId(task.getReceiverId());
        message.setCommonId(taskId);
        message.setType(3);
        message.setCreateTime(TimeConst.nowTimeMilli);
        message.setUpdateTime(TimeConst.nowTimeMilli);
        messageMapper.insertMessage(message);

        // 持久化佣金记录
        Commission commission = new Commission();
        commission.setCommissionId(commissionWorker.nextId());
        commission.setTaskId(taskId);
        commission.setUserId(task.getReceiverId());
        commission.setTaskTitle(task.getTitle());
        commission.setReward(task.getReward());
        commissionMapper.insertCommission(commission);

        // 更新用户总的佣金值
        userMapper.updateCommissionByUserId(task.getReward(),task.getReceiverId());
        return true;
    }
}
